/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation * (report 36180: Callers/Callees view) *******************************************************************************/ package org.eclipse.jdt.internal.corext.callhierarchy; import java.util.ArrayList; import java.util.Collection; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.JavaPlugin; /** * The main plugin class to be used in the desktop. */ public class Implementors { private static IImplementorFinder[] IMPLEMENTOR_FINDERS= new IImplementorFinder[] { new JavaImplementorFinder() }; private static Implementors fgInstance; /** * Returns the shared instance. */ public static Implementors getInstance() { if (fgInstance == null) { fgInstance = new Implementors(); } return fgInstance; } /** * Searches for implementors of the specified Java elements. Currently, only IMethod * instances are searched for. Also, only the first element of the elements * parameter is taken into consideration. * * @param elements * * @return An array of found implementing Java elements (currently only IMethod * instances) */ public IJavaElement[] searchForImplementors(IJavaElement[] elements, IProgressMonitor progressMonitor) { if ((elements != null) && (elements.length > 0)) { IJavaElement element = elements[0]; try { if (element instanceof IMember) { IMember member = (IMember) element; IType type = member.getDeclaringType(); if (type.isInterface()) { IType[] implementingTypes = findImplementingTypes(type, progressMonitor); if (member.getElementType() == IJavaElement.METHOD) { return findMethods((IMethod)member, implementingTypes, progressMonitor); } else { return implementingTypes; } } } } catch (JavaModelException e) { JavaPlugin.log(e); } } return null; } /** * Searches for interfaces which are implemented by the declaring classes of the * specified Java elements. Currently, only IMethod instances are searched for. * Also, only the first element of the elements parameter is taken into * consideration. * * @param elements * * @return An array of found interfaces implemented by the declaring classes of the * specified Java elements (currently only IMethod instances) */ public IJavaElement[] searchForInterfaces(IJavaElement[] elements, IProgressMonitor progressMonitor) { if ((elements != null) && (elements.length > 0)) { IJavaElement element = elements[0]; if (element instanceof IMember) { IMember member = (IMember) element; IType type = member.getDeclaringType(); IType[] implementingTypes = findInterfaces(type, progressMonitor); if (!progressMonitor.isCanceled()) { if (member.getElementType() == IJavaElement.METHOD) { return findMethods((IMethod)member, implementingTypes, progressMonitor); } else { return implementingTypes; } } } } return null; } private IImplementorFinder[] getImplementorFinders() { return IMPLEMENTOR_FINDERS; } private IType[] findImplementingTypes(IType type, IProgressMonitor progressMonitor) { Collection<IType> implementingTypes = new ArrayList<IType>(); IImplementorFinder[] finders = getImplementorFinders(); for (int i = 0; (i < finders.length) && !progressMonitor.isCanceled(); i++) { Collection<IType> types = finders[i].findImplementingTypes(type, new SubProgressMonitor(progressMonitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); if (types != null) { implementingTypes.addAll(types); } } return implementingTypes.toArray(new IType[implementingTypes.size()]); } private IType[] findInterfaces(IType type, IProgressMonitor progressMonitor) { Collection<IType> interfaces = new ArrayList<IType>(); IImplementorFinder[] finders = getImplementorFinders(); for (int i = 0; (i < finders.length) && !progressMonitor.isCanceled(); i++) { Collection<IType> types = finders[i].findInterfaces(type, new SubProgressMonitor(progressMonitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); if (types != null) { interfaces.addAll(types); } } return interfaces.toArray(new IType[interfaces.size()]); } /** * Finds IMethod instances on the specified IType instances with identical signatures * as the specified IMethod parameter. * * @param method The method to find "equals" of. * @param types The types in which the search is performed. * * @return An array of methods which match the method parameter. */ private IJavaElement[] findMethods(IMethod method, IType[] types, IProgressMonitor progressMonitor) { Collection<IMethod> foundMethods = new ArrayList<IMethod>(); SubProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL); subProgressMonitor.beginTask("", types.length); //$NON-NLS-1$ try { for (int i = 0; i < types.length; i++) { IType type = types[i]; IMethod[] methods = type.findMethods(method); if (methods != null) { for (int j = 0; j < methods.length; j++) { foundMethods.add(methods[j]); } } subProgressMonitor.worked(1); } } finally { subProgressMonitor.done(); } return foundMethods.toArray(new IJavaElement[foundMethods.size()]); } }